import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QFileDialog
from PyQt5 import QtWidgets, QtCore, QtGui
from map import Ui_Form
import folium
from PyQt5.QtWebEngineWidgets import *
import os
import pandas as pd
import numpy as np

# Map = folium.Map(location=[39.904030, 116.407526],
#                  zoom_start=16,
#                  control_scale=True,
#                  tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}',
#                  attr='default')
#
#
# Map.add_child(folium.LatLngPopup())                     # 显示鼠标点击点经纬度
# Map.add_child(folium.ClickForMarker(popup='Waypoint'))  # 将鼠标点击点添加到地图上

# def parse_zhch(s):
#     return str(str(s).encode('ascii' , 'xmlcharrefreplace'))[2:-1]

# 悬浮弹出信息
# tooltip = parse_zhch('嘿！')
# folium.Marker([31.2453,121.4857], popup=parse_zhch('外白渡桥'), tooltip=tooltip).add_to(Map)
# folium.Marker([31.2418,121.4953], popup=parse_zhch('东方明珠'), icon=folium.Icon(color='green'),tooltip=tooltip).add_to(Map)
# folium.PolyLine(
#     locations=[
#         [31.24464,121.48348],
#         [31.24318,121.48262],
#         [31.23969,121.48433],
#         [31.24014,121.49171]
#     ],
#     popup=parse_zhch('路径测试'),
#     color='red'
# ).add_to(Map)
# Map.save("save_map.html")


class Map(QWidget, Ui_Form):
    def __init__(self):
        super(Map, self).__init__()
        self.setupUi(self)
        self.qwebengine = QWebEngineView(self)
        self.Map = folium.Map(location=[39.904030, 116.407526],
                         zoom_start=16,
                         control_scale=True,
                         tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}',
                         attr='default')

        # self.Map.add_child(folium.LatLngPopup())  # 显示鼠标点击点经纬度
        # self.Map.add_child(folium.ClickForMarker(popup='Waypoint'))  # 将鼠标点击点添加到地图上
        self.Map.save("save_map.html")
        path = "file:\\" + os.getcwd() + "\\save_map.html"
        path = path.replace('\\', '/')
        self.qwebengine.load(QUrl(path))
        self.h1_layout = QtWidgets.QHBoxLayout()
        self.groupBox.setLayout(self.h1_layout)
        self.h1_layout.addWidget(self.qwebengine)

        self.param_init()
        self.button_init()

    def button_init(self):
        self.search_button.clicked.connect(self.search)
        self.reset_button.clicked.connect(self.reset_bu)
        self.clear_button.clicked.connect(self.clear)

    def reset(self):
        self.Map = folium.Map(location=[39.904030, 116.407526],
                              zoom_start=16,
                              control_scale=True,
                              tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}',
                              attr='default')
        self.Map.save("save_map.html")
        path = "file:\\" + os.getcwd() + "\\save_map.html"
        path = path.replace('\\', '/')
        self.qwebengine.load(QUrl(path))

    def reset_bu(self):
        self.reset()
        self.Start_node.clear()
        self.end_node.clear()

    def clear(self):
        self.textEdit.clear()

    def param_init(self):
        df = pd.read_csv('location.csv')
        self.dic_location = {}
        for key, value in zip(df['城市'], zip(df['lat'], df['lon'])):
            self.dic_location[key] = value

        data = pd.read_csv('dis.csv')
        src = list(data['src'])
        dst = list(data['dst'])

        self.dic_neighbour = {}
        lis = list(data['src'])
        for i in range(len(lis)):
            if lis[i] not in self.dic_neighbour:
                self.dic_neighbour[lis[i]] = [data['dst'][i]]
            else:
                self.dic_neighbour[lis[i]].append(data['dst'][i])
        lis = list(data['dst'])
        for i in range(len(lis)):
            if lis[i] not in self.dic_neighbour:
                self.dic_neighbour[lis[i]] = [data['src'][i]]
            else:
                self.dic_neighbour[lis[i]].append(data['src'][i])

        self.dic = {}
        for i in range(len(src)):
            if src[i] not in self.dic:
                self.dic[src[i]] = len(self.dic)
        for i in range(len(dst)):
            if dst[i] not in self.dic:
                self.dic[dst[i]] = len(self.dic)

        self.distance = np.zeros((188, 188))
        for i in range(data.shape[0]):
            self.distance[self.dic[data['src'][i]], self.dic[data['dst'][i]]] = self.distance[self.dic[data['dst'][i]], self.dic[data['src'][i]]] = \
            data['distance'][i]



    def parse_zhch(self, s):
        return str(str(s).encode('ascii', 'xmlcharrefreplace'))[2:-1]

    def update(self):
        self.Map.save("save_map.html")
        path = "file:\\" + os.getcwd() + "\\save_map.html"
        path = path.replace('\\', '/')
        self.qwebengine.load(QUrl(path))

    def draw_start(self, city):

        # 悬浮弹出信息
        tooltip = self.parse_zhch('起点！')
        folium.Marker(self.dic_location[city], popup=self.parse_zhch(city), icon=folium.Icon(color='green'),tooltip=tooltip).add_to(self.Map)
        self.update()

    def draw_end(self, city):
        # 悬浮弹出信息
        tooltip = self.parse_zhch('终点！')
        folium.Marker(self.dic_location[city], popup=self.parse_zhch(city), icon=folium.Icon(color='red'),tooltip=tooltip).add_to(self.Map)
        self.update()

    def draw_mid(self):
        # 悬浮弹出信息
        for i in range(len(self.path)-2,0,-1):
            tooltip = self.parse_zhch(f'第{(len(self.path)-1-i)}跳城市节点！')
            folium.Marker(self.dic_location[self.path[i]], popup=self.parse_zhch(self.path[i]), tooltip=tooltip).add_to(self.Map)
        self.update()

    def draw_path(self):
        loc=[]
        for i in self.path:
            loc.append(self.dic_location[i])
        folium.PolyLine(
            locations=loc,
            popup=self.parse_zhch('路径测试'),
            color='red'
        ).add_to(self.Map)
        self.update()

    def search(self):
        self.reset()
        start = self.Start_node.text()
        end = self.end_node.text()

        class node:
            def __init__(self, city, neighbour, pre=None, current=float('inf')):
                self.city = city
                self.pre = pre
                self.current = current
                self.neighbour = neighbour

        City = []
        for key, value in self.dic.items():
            Node = node(key, self.dic_neighbour[key])
            City.append(Node)

        temp = start
        find = [start]
        feasible = []

        while end not in find:
            for city in City[self.dic[temp]].neighbour:
                if city not in feasible and city not in find:
                    feasible.append(city)
                    City[self.dic[city]].current = City[self.dic[temp]].current + self.distance[self.dic[temp], self.dic[city]]
                    City[self.dic[city]].pre = temp
                elif city in feasible and city not in find:
                    dis = City[self.dic[temp]].current + self.distance[self.dic[temp], self.dic[city]]
                    if dis < City[self.dic[city]].current:
                        City[self.dic[city]].current = dis
                        City[self.dic[city]].pre = temp
            min_ix = 0
            for i in range(len(feasible)):
                if City[self.dic[feasible[i]]].current < City[self.dic[feasible[min_ix]]].current:
                    min_ix = i
            temp = feasible.pop(min_ix)
            find.append(temp)
        self.path = [end]
        temp = end
        while City[self.dic[temp]].pre != None:
            temp = City[self.dic[temp]].pre
            self.path.append(temp)
        self.draw_start(start)
        self.draw_end(end)
        self.draw_path()
        self.draw_mid()
        self.textEdit.clear()
        self.textEdit.append('起点：'+self.path[-1])
        for i in range(len(self.path)-2, 0, -1):
            self.textEdit.append(f'第{(len(self.path)-1-i)}跳城市节点:'+self.path[i])
        self.textEdit.append('终点：'+self.path[0])
        print('start:',self.dic_location[start])
        print('end:',self.dic_location[end])
        print(self.path)


if __name__=='__main__':
    app = QApplication(sys.argv)
    map = Map()
    map.show()
    sys.exit(app.exec_())